use {
    crate::biz::{collect_service, recharge_service},
    repository::model::{
        dapp_centralized_config::DAppCentralizedConfig,
        dapp_transaction::{DAppTransaction, TransactionStatus},
    },
    sqlx::{MySql, Pool},
    tracing::{debug, error},
};

const CHAIN: &str = "TRON";
pub async fn recharge_job(env: &str, pool: &Pool<MySql>) -> anyhow::Result<()> {
    let mut interval_timer = tokio::time::interval(std::time::Duration::from_secs(60));
    loop {
        interval_timer.tick().await;
        let transaction_entites_ret = DAppTransaction::select_all_unprocessed(CHAIN, &pool).await;
        if let Err(e) = transaction_entites_ret {
            error!("select dapp_transaction error: {e}");
            continue;
        }
        let transaction_entites = transaction_entites_ret.unwrap();

        for transaction in transaction_entites {
            let hash = transaction.recharge_hash.clone();
            match recharge_service::recharge_remote(env, CHAIN, pool, &transaction).await {
                Ok(_) => continue,
                Err(e) => {
                    DAppTransaction::update_status(
                        &pool,
                        transaction.id.unwrap(),
                        u8::from(TransactionStatus::Unprocessed),
                    )
                    .await;
                    error!("{hash} recharge error: {e}");
                }
            }
        }
    }
}

pub async fn collect_job(env: &str, pool: &Pool<MySql>) -> anyhow::Result<()> {
    let mut interval_timer = tokio::time::interval(std::time::Duration::from_secs(60));

    loop {
        interval_timer.tick().await;
        let dapp_centralized_config_ret = DAppCentralizedConfig::select_by_chain(CHAIN, pool).await;
        if let Err(e) = dapp_centralized_config_ret {
            error!("select dapp_centralized_config error: {e}");
            continue;
        }
        let transaction_entites_ret =
            DAppTransaction::select_all_recharge_successed(CHAIN, pool).await;
        if let Err(e) = transaction_entites_ret {
            error!("select dapp_transaction error: {e}");
            continue;
        }

        let dapp_centralized_config = dapp_centralized_config_ret.unwrap();
        let transaction_entites = transaction_entites_ret.unwrap();

        for transaction in transaction_entites {
            let id = transaction.id.unwrap();
            debug!("collect job [{id}] start...");
            match collect_service::collect_job(
                env,
                CHAIN,
                pool,
                &dapp_centralized_config,
                &transaction,
            )
            .await
            {
                Ok(_) => continue,
                Err(e) => {
                    let b = e.backtrace();
                    error!("collect job [{id}] error: {:?}. \n{}", e, b);
                    DAppTransaction::update_status(
                        &pool,
                        id,
                        u8::from(TransactionStatus::RechargeSuccess),
                    )
                    .await;
                }
            }
        }
    }
}
